﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AccessControl.Video.Rtp;
using System.Net.Sockets;
using System.Threading;

namespace AccessControl.Video.Rtsp
{
	/// <summary>
	/// Represents RTP socket
	/// </summary>
	/// <remarks></remarks>
	class RtpSocket : SocketBase
	{
		#region Fields

		bool _running;
		UdpClient _socket;
		Thread _socketThread;

		#endregion

		#region Public Properties

		public byte[] SPS { get; set; }
		public byte[] PPS { get; set; }

		#endregion

		#region Public Members

		/// <summary>
		/// Initializes this instance.
		/// </summary>
		/// <returns></returns>
		/// <remarks></remarks>
		public override bool Initialize()
		{
			if (_socket != null)
				return false;

			try { _socket = new UdpClient(PortNumber); }
			catch
			{
				System.Diagnostics.Debug.WriteLine("Failed to create socket");
				return false;
			}

			_running = true;
			_socketThread = new Thread(SocketThread) { IsBackground = true };
			_socketThread.Start();

			return true;
		}

		/// <summary>
		/// Terminates this instance.
		/// </summary>
		/// <returns></returns>
		/// <remarks></remarks>
		public override bool Terminate()
		{
			_running = false;
			_socketThread.Join();
			_socketThread = null;

			try { _socket.Close(); }
			catch { }

			return true;
		}

		#endregion

		#region Public Delegates 

		public delegate void NewRtpPacketEventHandler(RtpPacket packet);

		#endregion

		#region Public Events

		public event NewRtpPacketEventHandler NewRtpPacket;

		#endregion

		#region Private Members

		private void SocketThread()
		{
			int nRead;
			byte[] aBytes = new byte[2048];
			List<Socket> read = new List<Socket>();

			while (_running)
			{
				read.Clear();
				read.Add(_socket.Client);

				Socket.Select(read, null, null, 100 * 1000);
				foreach (Socket socket in read)
				{
					aBytes = new byte[2048];
					nRead = socket.Receive(aBytes);
					byte[] rtpPacket = new byte[nRead];
					Array.Copy(aBytes, rtpPacket, nRead);
					H264RtpPacket packet = new H264RtpPacket(rtpPacket, SPS, PPS);
					if (NewRtpPacket != null)
						NewRtpPacket(packet);
				}
			}
		}

		#endregion
	}
}
